<?php

/* 
 * 支付宝支付
 * @author wyb
 */
namespace app\common\extend\pay;
class Alipay {
    
    private $_appid = '2088431761552677';
    
    private $_service = 'mobile.securitypay.pay';
    
    private $_notify_url = 'http://m.enfukeji.com/notice.php/task/notify/order/type/alipay';
    
    private $_seller_id = '770154955@qq.com';
    
    private $_private_key_path = ''; //rsa密匙路径
    
    private $_public_key = ''; //rsa公匙路径
	
	private $_private_key = '';
    
    private $_data = []; //请求的数据
    
    public function __construct() {
        $this->_private_key_path = dirname(__FILE__) . '/alipay/rsa_private_key.pem';
		$this->_private_key = 'MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCX8c8q/yc3dmOmIuxfJolWFi1zRQMCyz0nTLBL/J/Ohh+ajHmqkzki8JvjHDauxY7nVsf3pjTtLjOkH4oLEcPhFuMShsbRLd5BnflRQ6eNwLHRqS5y6BUUo7BWPtrSoEs+xlqdrXeIvUBm7BlSkSdsZnY03HcRXTyx1YNEiuDgNYUWuc8g/kl0DG9Yq8fP7uL/LnKGdPDpGWN6dAvz5zyS4yiDlJMcKB6ixr/XkR/dNPGTeKzZaYV7VtMZo9xElNarLTO0ajIUAXScteV9VZhp3PT12FAJhDPz9hqnvPwUVHvWzQ0J8SD2CMU8Hn84h+f+GQ8y7uPpXgwtOuJTfbT1AgMBAAECggEAXQX62o0JumftzBnXcs2KCT1cqBSZKk25a+UEjhDk2bC9ioX0Ot0VfvGlzp5IUCm9Op6joFeOUaMWlKWGgw5mSNkVPhNrh0c4qh2INRthamSNuRmFyW2S8mbgn3ytxYPDbXRMp/o6k2miEyD6w9UAONpmBijvcJ8PeKSKUB1iXYERFTN7uUoMvm5Dy+dgejbhU1/W1uM5+Oi2bPIPlBzKa70BaK/YaeT1HU/ROnZGlyRL+z2rkxV10OXD1NR6+OFZyGDmPqtFhxBQSBrljU/GMJhPjuZemMg2+063vtSQsh3abVgVw3EXUp0V1PzTIzloNEDiG5JEthqmKtwCKf6dYQKBgQDtJgQ8B9lHcRCBfYhlohvXASK0jQYU5BFHIahiZvdWtAhY2dgI4tF7omNCbqZOgVhXBNWga3ptamw4A0c6N8ltapXkYb/ZGiFaO7GZ1N2IndNEvsiNaHd6lmHo0MwXQYmw2pmX7EqMGXXQyK1rJkiLbeBe8VATGG3Iq/Z2GQzIOQKBgQCkBeN2eI1E+iDJgYMMaqIutNYZ0liuoPa8HR+FznlY2RWKqUNBMH4rZKggZrgc0sRolsfOni0A4+fQHGOqWtzjn5Pq+z6Zz7VfFix83LwoA7xBTBXbU5sY7xXbP3tGSSat/3ICkmZbq3Yu0xeZYfRBYPR8fuuw6xOfPSLul5o6nQKBgCekIjMSsMxTZwnuPP2YMoUnKHD73ddiJE06oBYK1i+FGpwXlhguKgw7odH6Awy+bFDnevo83RMrJfna+m4N4zrKBVJO0K3uw0J9Ffv77CgpEaa9KXMR0l8IgkdTl7oPd3+7ms8dbXyryNjkorB1jszXyhi0x8jZXYiczi8BkvRpAoGAK57ZSEd1InP2xkAoLuQo74zuJ33WUdLC63I/UOGBSgypeu/az/pqg3XIdJ18t0WiMEJxLtTIGSWDH8h9BPAXMH3e464fjt47WOdXu3kknOupZCAs6+BHLhFfWah/S0jm/X0iv+ZZTGXED13aN9NiFwUG4BkM60cJN98VbChrPs0CgYAfbFlalFDtOiEHB3Hm6A/z6jQDBAVfJClVhI/DEM7iij9borz282Qmq0KC63i0vv3ip3WJg1Rseo3DOtFkvPCALuIafOYsfHce9vsQPGRD9s1cg6+RPV1OtVHHv8F0WHN8NQ5ogqoWCszTY5Mh0uaImzahhcVlkIF09AriqCIn7A==';
        $this->_public_key = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnxj/9qwVfgoUh/y2W89L6BkRAFljhNhgPdyPuBV64bfQNN1PjbCzkIM6qRdKBoLPXmKKMiFYnkd6rAoprih3/PrQEB/VsW8OoM8fxn67UDYuyBTqA23MML9q1+ilIZwBC2AQ2UBVOrFXfFl75p6/B5KsiNG9zpgmLCUYuLkxpLQIDAQAB";
    }
    
    /**
     * 生成支付字符串
     * @return type
     */
    public function pay( $order_info ) {
            $this->_data = [
                    'partner' => $this->_appid, //应用APPID
                    'service' => $this->_service, //访问接口
                    '_input_charset' => 'utf-8',//请求编码
                    'notify_url' => $this->_notify_url,
                    'out_trade_no' 	=> $order_info['order_sn'] . '_' . $order_info['order_type'], //订单号
                    'subject'		=> $order_info['body'], //产品标题
                    'payment_type'	=> 1,
                    'seller_id'		=> $this->_seller_id,
                    'total_fee'         => $order_info['total_price'],//支付金额
                    'body'		=> $order_info['body']
            ];
			$this->_data .= '&sign="' . urlencode( $this->_aign() ) . '"&sign_type="RSA"';
            return ['data' => $this->_data , 'status' => true ];
    }
    
    /**
     * 签名价签
     * @return type
     */
    private function _aign() {
		ksort( $this->_data );
        $aign_data = [];
        foreach( $this->_data  as $k => $v ) {
                $aign_data[] = trim($k).'="'.trim($v).'"';
        }
        $this->_data = implode('&',$aign_data );
        //$priKey = file_get_contents( $this->_private_key_path );
		$priKey = "-----BEGIN RSA PRIVATE KEY-----\n" .
               wordwrap($this->_private_key, 64, "\n", true) .
               "\n-----END RSA PRIVATE KEY-----";
        $res = openssl_get_privatekey($priKey);
        ($res) or die('价签错误啦');
        openssl_sign( $this->_data , $sign, $res);
        openssl_free_key($res);
        $sign = base64_encode($sign);
        return $sign;
    }
    
    /**
     * 签名价签
     * @return type
     */
    private function _aignData() {
        ksort( $this->_data );
        $aign_data = [];
        $sgin_url = [];
        foreach( $this->_data  as $k => $v ) {
                $aign_data[] = trim($k).'='.( is_array( $v ) ? json_encode( $v ) : trim($v) );
                $sgin_url[] = trim($k).'='.( is_array( $v ) ? json_encode( $v ) : urlencode(trim($v) ));
        }
        $this->_data = implode('&',$sgin_url );
        //$priKey = file_get_contents( $this->_private_key_path );
        $priKey = "-----BEGIN RSA PRIVATE KEY-----\n" .
               wordwrap($this->_private_key, 64, "\n", true) .
               "\n-----END RSA PRIVATE KEY-----";
		$res = openssl_get_privatekey($priKey);
        ($res) or die('价签错误啦');
        openssl_sign( implode('&',$aign_data ) , $sign, $res);
        openssl_free_key($res);
        $sign = base64_encode($sign);
        return $sign;
    }
    
    function verify( $sign )  {
        ksort( $this->_data );
        reset( $this->_data );
        $aign_data = [];
        foreach( $this->_data  as $k => $v ) {
                $aign_data[] = trim($k).'='.trim($v).'';
        }
        $this->_data = implode('&',$aign_data );
        $priKey = "-----BEGIN PUBLIC KEY-----\n" .
               wordwrap($this->_public_key, 64, "\n", true) .
               "\n-----END PUBLIC KEY-----";
		$res = openssl_get_publickey($priKey);
        ($res) or die('价签错误啦');
        $result = (bool)openssl_verify($this->_data, base64_decode($sign), $res);
        openssl_free_key($res);
        return $result;

    }
    
    /**
     * 支付回调
     */
    public function notify() {
        $data = $_POST;
        if( !$data ) return false;
        if( $this->_notifyVerify( $data['notify_id'] ) != 'true' ) {
            return false;
        }
        if( !isset( $data['trade_status'] ) || !in_array( $data['trade_status'] ,[ 'TRADE_SUCCESS' , 'TRADE_FINISHED' ] ) ) return false;
        //签名认证
        $sign = $data['sign'];
        unset( $data['sign'] );
        unset( $data['sign_type'] );
        $this->_data = $data;
        if( $this->verify( $sign ) === false ) return false;
        $order_sn = explode( '_' , $data['out_trade_no'] );
        echo "success";
		return [
			'ordersn' => $order_sn[0],
			'type' => $order_sn[1],
			'trade_no' => $data['trade_no'],
			'price' => $data['total_fee']
		];
    }

    /**
     * 支付宝退款
     */
    public function orderRefund( $order_data , $price) {
        $this->_url = 'https://mapi.alipay.com/gateway.do';
        $this->_data = array(
                'app_id' => '2016101902242899', //应用APPID
                'method' => 'alipay.trade.refund',
                'charset' => 'utf-8',//请求编码
                'sign_type' => 'RSA',
                'timestamp' => date('Y-m-d H:i:s'),
                'version' => '1.0',
                'biz_content' => array(
                    'trade_no' => $order_data['payment_no'],
                    'refund_amount' => $price
                )
        );
        $this->_data .= '&sign=' . urlencode( $this->_aignData() );// . '"&sign_type="RSA"';
        $result = json_decode( $this->_send( $this->_url . '?' . $this->_data ) , true );
        if( $result ) {
            //支付成功
            if( $result['alipay_trade_refund_response']['code'] == 10000 ) {
                return array( 'msg' => '退款成功' , 'status' => true );
            } else { //支付失败
                return array( 'msg' => "code：". $result['alipay_trade_refund_response']['sub_code'] . " 错误描述：".$result['alipay_trade_refund_response']['sub_msg'] , 'status' => false );
            }
        } else {
            return array( 'msg' => '支付异常，请联系客服！' , 'status' => false );
        }
    }

    /**
     * 退款查询
     */
    public function refundQuery( $order_data ) {
        $this->_data = array(
                'app_id' => $this->_appid, //应用APPID
                'method' => 'alipay.trade.fastpay.refund.query',
                'charset' => 'utf-8',//请求编码
                'sign_type' => 'RSA',
                'timestamp' => date('Y-m-d H:i:s'),
                'version' => '1.0',
                'biz_content' => array(
                    'out_trade_no' => $order_data['ref'],
                    'out_request_no' => $order_data['payment_no']
                )
        );
        $this->_data .= '&sign="' . urlencode( $this->_aign() );// . '"&sign_type="RSA"';
        $result = json_decode( $this->_send( $this->_url . '?' . $this->_data ) , true );
        if( $result ) {
            $msg = '';
            //退款成功
            if( $result['alipay_trade_fastpay_refund_query_response']['code'] == 10000 && $result['alipay_trade_fastpay_refund_query_response']['msg'] == 'Success') {
                return true;
            }
            return false;
        } else {
            return false;
        }
    }
    
    public function _send( $url ) {
        $ci = curl_init( $url );
        curl_setopt( $ci, CURLOPT_RETURNTRANSFER, true);
        curl_setopt( $ci, CURLOPT_SSL_VERIFYPEER, FALSE); 
        curl_setopt( $ci, CURLOPT_SSL_VERIFYHOST, FALSE);
        $result = curl_exec( $ci );
        $status = curl_getinfo($ci);
        curl_close($ci);
        return $result;
    }
    
    /**
     * 发送请求
     */
    private function _notifyVerify( $notify_id ) {
        $ci = curl_init( "https://mapi.alipay.com/gateway.do?service=notify_verify&partner={$this->_appid}&notify_id={$notify_id}" );
        curl_setopt( $ci, CURLOPT_RETURNTRANSFER, true);
        curl_setopt( $ci, CURLOPT_SSL_VERIFYPEER, FALSE); 
        curl_setopt( $ci, CURLOPT_SSL_VERIFYHOST, FALSE);
        $result = curl_exec( $ci );
        curl_close($ci);
        return $result;
    }
}

